package com.littcore.saap.system.web;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.beanutils.BeanUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.ModelAndView;

import com.littcore.common.Utility;
import com.littcore.exception.NotLoginException;
import com.littcore.saap.common.vo.LoginUserVo;
import com.littcore.saap.common.vo.TenantUserVo;
import com.littcore.saap.core.common.SaapConstants.UserGroupType;
import com.littcore.saap.core.model.CheckItem;
import com.littcore.saap.core.web.util.LoginUtils;
import com.littcore.saap.system.biz.IUserBizService;
import com.littcore.saap.system.bo.UserGroupBo;
import com.littcore.saap.system.po.UserGroup;
import com.littcore.saap.system.po.UserGroupMember;
import com.littcore.saap.system.po.UserInfo;
import com.littcore.saap.system.service.IUserGroupMemberService;
import com.littcore.saap.system.service.IUserGroupService;
import com.littcore.saap.system.vo.UserGroupTreeNode;
import com.littcore.web.mvc.action.BaseController;
import com.littcore.module.annotation.Func;

/**
 * 
 * Groups controller.
 * <pre><b>Description：</b>
 *    Group Management
 * </pre>
 * 
 * @author <a href="mailto:littcai@hotmail.com">Bob.cai</a>
 * @since 2014-02-27
 * @version 1.0
 */
@Controller
public class UserGroupController extends BaseController
{
	private final static Logger logger = LoggerFactory.getLogger(UserGroupController.class);

	@Resource
	private IUserGroupService userGroupService;
	@Resource
	private IUserGroupMemberService userGroupMemberService;
	@Resource
	private IUserBizService userBizService;
	
	/**
	 * default page.
	 * 
	 * @param request the request
	 * @param respnose the respnose
	 * 
	 * @return ModelAndView
	 */	
	@Func(funcCode="query", moduleCode="tenant.userGroup", enableLog=false) 
	@RequestMapping 
	public ModelAndView index(WebRequest request, ModelMap modelMap) throws NotLoginException
	{	
		LoginUserVo loginUserVo = (LoginUserVo)super.getLoginVo();
		
		//get params from request		
		int currentId = Utility.parseInt(request.getParameter("currentId"));
		
		UserGroup currentUserGroup = null;
		if(currentId>0)
		{
		  currentUserGroup = userGroupService.load(currentId);
		  if(UserGroupType.GROUP == currentUserGroup.getType())
		  {
		    List<Map<String, Object>> memberList = userGroupMemberService.listWithUserInfoByGroup(currentId);
		    modelMap.addAttribute("memberList", memberList); 
		  }
		}
		//Get page result
		UserGroupTreeNode userGroupTree = userGroupService.findTree(loginUserVo.getTenantId());
		UserGroupTreeNode rootNode = userGroupTree.takeRoot(currentId); //当前节点的根父节点
		List<UserGroupBo> subUserGroupList = userGroupService.findByParent(loginUserVo.getTenantId(), currentId);
		
		//return params to response
		modelMap.addAttribute("rootNode", rootNode); 
		modelMap.addAttribute("currentUserGroup", currentUserGroup);  
		modelMap.addAttribute("userGroupTree", userGroupTree);	
		modelMap.addAttribute("subUserGroupList", subUserGroupList);  
    return new ModelAndView("/system/userGroup/index");	
	
	} 	
	
    
	/**
	 * Gets the by id.
	 *
	 * @param id the id
	 * @return ModelAndView
	 */
	@Func(funcCode="query", moduleCode="tenant.userGroup", enableLog=false)  
	@RequestMapping 
	public ModelAndView getById(@RequestParam Integer id) 
	{ 
		UserGroup userGroup = userGroupService.load(id);		
    return new ModelAndView("jsonView").addObject("userGroup", userGroup);
  }   
	    
  /**
	 * Save.
	 * @param request 
	 * @param modelMap
	 * @throws Exception 
	 */
	@Func(funcCode="add",moduleCode="tenant.userGroup")
	@RequestMapping 
	public void save(WebRequest request, ModelMap modelMap) throws Exception
	{	
		UserGroup userGroup = new UserGroup();
		BeanUtils.populate(userGroup, request.getParameterMap());			
		userGroupService.save(userGroup);
	}
	
	/**
	 * Update.
	 * @param request 
	 * @param modelMap
	 * @throws Exception 
	 */
	@Func(funcCode="edit",moduleCode="tenant.userGroup")
	@RequestMapping 
	public void update(WebRequest request, ModelMap modelMap) throws Exception
	{
		UserGroup userGroup = userGroupService.load(Utility.parseInt(request.getParameter("id")));
		BeanUtils.populate(userGroup, request.getParameterMap());
		userGroupService.update(userGroup);
	}
	
	/**
	 * Delete.
	 * @param id id
	 * @throws Exception 
	 */
	@Func(funcCode="delete",moduleCode="tenant.userGroup")
	@RequestMapping 
	public void delete(@RequestParam Integer id) throws Exception
	{
		userGroupService.delete(id);
	}

	/**
	 * Delete Batch.
	 * @param id id
	 * @throws Exception 
	 */
	@Func(funcCode="delete",moduleCode="tenant.userGroup")
	@RequestMapping 
	public void deleteBatch(@RequestParam(value="ids[]") Integer[] ids) throws Exception
	{
		userGroupService.deleteBatch(ids);
	}
	
	@RequestMapping 
	public ModelAndView getTenantMembers(@RequestParam Integer userGroupId)
	{
	  int tenantId = LoginUtils.getTenantId();
	  
	  List<TenantUserVo> tenantUserList = userBizService.findByTenant(tenantId);
	  List<UserGroupMember> memberList = userGroupMemberService.listByGroup(userGroupId);
	  	  
    List<CheckItem<TenantUserVo>> tenantUserCheckItemList = new ArrayList<CheckItem<TenantUserVo>>();
    for (TenantUserVo tenantUser : tenantUserList) {
      boolean isChecked = false;
      for (UserGroupMember userGroupMember : memberList) {
        if(tenantUser.getId().equals(userGroupMember.getUserId()))
        {
          isChecked = true;
          break;
        } 
      }
      CheckItem<TenantUserVo> checkItem = new CheckItem<TenantUserVo>(isChecked, tenantUser);
      tenantUserCheckItemList.add(checkItem);
    }
    return new ModelAndView("jsonView").addObject("tenantUserList", tenantUserCheckItemList);
	}
	
	/**
   * Add Page.
   * 
   * @return ModelAndView
   */ 
  @Func(funcCode="addMember", moduleCode="tenant.userGroup", enableLog=false)  
  @RequestMapping
  public ModelAndView addMember() 
  {        
    return new ModelAndView("/system/userGroup/addMember");
  }  
  
  /**
   * Show Page.
   * 
   * @param id 
   * 
   * @return ModelAndView
   */
  @Func(funcCode="query", moduleCode="tenant.userGroup", enableLog=false)  
  @RequestMapping 
  public ModelAndView showMembers(@RequestParam Integer id) 
  { 
    UserGroup userGroup = userGroupService.load(id);
    
    List<Map<String, Object>> memberList = userGroupMemberService.listWithUserInfoByGroup(id);
    
    return new ModelAndView("/system/userGroup/showMembers")
            .addObject("userGroup", userGroup)
            .addObject("memberList", memberList);
  }   
  
  /**
   * Save.
   * @param request 
   * @param modelMap
   * @throws Exception 
   */
  @Func(funcCode="addMember",moduleCode="tenant.userGroup")
  @RequestMapping 
  public void saveMemberBatch(@RequestParam Integer groupId, @RequestParam(value="userIds[]") Integer[] userIds) throws Exception
  { 
    userGroupMemberService.saveBatch(groupId, userIds);
  }
  
  /**
   * Delete.
   * @param id id
   * @throws Exception 
   */
  @Func(funcCode="deleteMember",moduleCode="tenant.userGroup")
  @RequestMapping 
  public void deleteMember(@RequestParam Integer id) throws Exception
  {
    userGroupMemberService.delete(id);
  }
  

  /**
   * Delete Batch.
   * @param id id
   * @throws Exception 
   */
  @Func(funcCode="deleteMember",moduleCode="tenant.userGroup")
  @RequestMapping 
  public void deleteMemberBatch(@RequestParam(value="ids[]") Integer[] ids) throws Exception
  {
    userGroupMemberService.deleteBatch(ids);
  }
  
  @RequestMapping
  @ResponseBody
  public List<UserGroupTreeNode> getTree() {
    UserGroupTreeNode userGroupTree = userGroupService.findTree(LoginUtils.getTenantId());    
    List<UserGroupTreeNode> flatDirList = userGroupTree.takeFlatList();
    return flatDirList;
  }
  
  @RequestMapping
  @ResponseBody
  public List<UserGroup> getAllSubGroups(@RequestParam Integer parentId) {
    List<UserGroup> userGroupList = userGroupService.listAllSubByParent(LoginUtils.getTenantId(), parentId);
    
    return userGroupList;
  }
  
  @RequestMapping
  @ResponseBody
  public List<Map<String, Object>> getGroupMembers(@RequestParam Integer groupId) {
    List<Map<String, Object>> memberList = userGroupMemberService.listWithUserInfoByGroup(groupId);
    
    return memberList;
  }
  
  @RequestMapping
  @ResponseBody
  public List<UserInfo> getAllSubGroupMembers(@RequestParam Integer parentId) {    
    //TODO 这个又递归获取了一次userGroupIds，需要优化
    List<UserGroup> userGroupList = userGroupService.listAllSubByParent(LoginUtils.getTenantId(), parentId);
    Integer[] userGroupIds = new Integer[userGroupList.size()];
    for (int i = 0; i < userGroupList.size(); i++)
    {
      UserGroup userGroup = userGroupList.get(i);
      userGroupIds[i] = userGroup.getId();
    }
    List<UserInfo> memberList = userGroupMemberService.listAllSubGroupUsers(LoginUtils.getTenantId(), userGroupIds);
    
    return memberList;
  }
  
  @RequestMapping
  @ResponseBody
  public List<UserGroup> getGroupsById(@RequestParam(value = "groupIds[]",required=false) Integer[] groupIds) {
	  if(groupIds==null){
		  return new ArrayList<UserGroup>();
	  }
    List<UserGroup> userGroupList = userGroupService.listByGroupIds(LoginUtils.getTenantId(), groupIds);    
    return userGroupList;
  }

}
